package com.ruoyi.business.service.s7;

import cn.hutool.core.util.IdUtil;
import com.ruoyi.business.domain.AlarmInfo;
import com.ruoyi.business.domain.EquipmentVariables;
import com.ruoyi.business.domain.EquipmentVariablesHistory;
import com.ruoyi.business.domain.S7VariablesConfig;
import com.ruoyi.business.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * S7连接管理服务
 * 简化版S7数据读取和存储服务
 *
 * @author qiancheng
 * @date 2025-09-02
 */
@Service
public class S7ConnectionManagerService {
    private static final Logger log = LoggerFactory.getLogger(S7ConnectionManagerService.class);

    @Autowired
    private S7VariableManagerService s7VariableManagerService;

    @Autowired
    private IEquipmentVariablesService equipmentVariablesService;

    @Autowired
    private S7ConnectionPoolManager connectionPoolManager;

    @Autowired
    private IEquipmentVariablesHistoryService equipmentVariablesHistoryService;

    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
    private final AtomicInteger retryCount = new AtomicInteger(0);
    private final int MAX_RETRY_COUNT = 3;
    private boolean initialized = false;

    // 并行读取配置
    private static final boolean ENABLE_PARALLEL_READING = true; // 启用并行读取
    private static final int PARALLEL_BATCH_SIZE = 10; // 每批次变量数量

    // 历史数据记录配置
    private static final boolean ENABLE_HISTORY_RECORDING = true; // 启用历史数据记录

    // 新增：注入能源数据处理服务
    @Autowired
    private S7EnergyDataService energyDataService;

    @Autowired
    private IAlarmInfoService alarmService;

    /**
     * 初始化所有PLC连接池
     */
    @PostConstruct
    public void initializeAllConnections() {
        if (initialized) {
            return;
        }

        log.info("======= 开始初始化S7 PLC连接池 =======");

        List<String> plcIps = s7VariableManagerService.getAllPlcIps();

        for (String plcIp : plcIps) {
            try {
                List<S7VariablesConfig> variables = s7VariableManagerService.getVariablesByPlcIp(plcIp);
                connectionPoolManager.initializeConnectionPool(plcIp, variables);
            } catch (Exception e) {
                log.error("初始化PLC [{}] 连接池失败", plcIp, e);
            }
        }

        log.info("======= S7 PLC连接池初始化完成 =======");

        // 启动数据读取任务
        startDataReadingTask();
        initialized = true;
    }

    /**
     * 初始化指定PLC连接池
     */
    public boolean initializeConnection(String plcIp, List<S7VariablesConfig> variables) {
        try {
            CompletableFuture<Boolean> future = connectionPoolManager.initializeConnectionPool(plcIp, variables);
            return future.get(10, TimeUnit.SECONDS); // 等待初始化完成，最多10秒
        } catch (Exception e) {
            log.error("初始化PLC [{}] 连接池失败", plcIp, e);
            return false;
        }
    }

    /**
     * 启动数据读取任务
     */
    private void startDataReadingTask() {
        scheduler.scheduleWithFixedDelay(() -> {
            try {
                readAllActiveVariables();
            } catch (Exception e) {
                log.error("读取变量数据时发生异常", e);
            }
        }, 5, S7ConnectionPoolManager.DATA_ACQUISITION_INTERVAL, TimeUnit.SECONDS);

        log.info("数据读取任务已启动，每{}秒执行一次", S7ConnectionPoolManager.DATA_ACQUISITION_INTERVAL);
    }

    /**
     * 读取所有激活变量的值 - 并行读取版本
     */
    public void readAllActiveVariables() {
        log.info("开始并行读取所有激活变量的DB块数据...");
        long startTime = System.currentTimeMillis();

        List<String> plcIps = s7VariableManagerService.getAllPlcIps();

        if (plcIps.isEmpty()) {
            log.warn("未找到配置的PLC设备，无法读取变量值");
            return;
        }

        log.info("找到{}个PLC设备，开始并行读取", plcIps.size());

        // 为每个PLC创建并行读取任务
        List<CompletableFuture<Map<String, Object>>> plcReadTasks = new ArrayList<>();
        List<S7VariablesConfig> allVariables = new ArrayList<>();
        int connectedPlcs = 0;

        for (String plcIp : plcIps) {
            List<S7VariablesConfig> variables = s7VariableManagerService.getVariablesByPlcIp(plcIp);

            if (variables.isEmpty()) {
                log.warn("PLC [{}] 没有配置变量", plcIp);
                continue;
            }

            if (connectionPoolManager.isConnected(plcIp)) {
                allVariables.addAll(variables);
                connectedPlcs++;
                log.info("PLC [{}] 已连接，准备并行读取{}个变量", plcIp, variables.size());

                // 根据配置选择读取方式
                CompletableFuture<Map<String, Object>> plcTask = ENABLE_PARALLEL_READING
                    ? readVariablesFromSinglePLCParallel(plcIp, variables)
                    : readVariablesFromSinglePLC(plcIp, variables);
                plcReadTasks.add(plcTask);
            } else {
                log.warn("PLC [{}] 未连接，无法读取其{}个变量", plcIp, variables.size());
                // 尝试重新连接
                retryConnection(plcIp, variables);
            }
        }

        if (plcReadTasks.isEmpty()) {
            log.warn("没有可读取的PLC连接");
            return;
        }

        log.info("开始从{}个已连接PLC并行读取{}个变量的DB块数据", connectedPlcs, allVariables.size());

        // 并行执行所有PLC的读取任务
        CompletableFuture.allOf(plcReadTasks.toArray(new CompletableFuture[0]))
                .thenApply(v -> {
                    // 合并所有PLC的读取结果
                    Map<String, Object> allResults = new ConcurrentHashMap<>();
                    for (CompletableFuture<Map<String, Object>> task : plcReadTasks) {
                        try {
                            Map<String, Object> plcResults = task.get();
                            allResults.putAll(plcResults);
                        } catch (Exception e) {
                            log.error("获取PLC读取结果时发生异常", e);
                        }
                    }
                    return allResults;
                })
                .thenAccept(results -> {
                    long duration = System.currentTimeMillis() - startTime;
                    log.info("并行读取完成，成功读取{}个变量的DB块数据，用时{}ms",
                            results.size(), duration);

                    // 批量更新变量值到数据库
                    updateVariableValuesAsync(allVariables, results);
                })
                .exceptionally(throwable -> {
                    log.error("并行读取变量数据时发生异常", throwable);
                    return null;
                });
    }

    /**
     * 重试连接
     */
    private void retryConnection(String plcIp, List<S7VariablesConfig> variables) {
        int currentRetry = retryCount.getAndIncrement();
        if (currentRetry < MAX_RETRY_COUNT) {
            log.info("尝试重新连接PLC [{}]，第{}次重试", plcIp, currentRetry + 1);
            try {
                connectionPoolManager.initializeConnectionPool(plcIp, variables);
                retryCount.set(0); // 重置重试计数
            } catch (Exception e) {
                log.error("重新连接PLC [{}] 失败", plcIp, e);
            }
        } else {
            log.warn("PLC [{}] 连接重试次数已达上限{}", plcIp, MAX_RETRY_COUNT);
            retryCount.set(0); // 重置重试计数
        }
    }



    /**
     * 从单个PLC并行读取变量
     */
    private CompletableFuture<Map<String, Object>> readVariablesFromSinglePLCParallel(String plcIp, List<S7VariablesConfig> variables) {
        Map<String, Object> results = new ConcurrentHashMap<>();

        // 将变量分批，每批使用一个连接
        int batchSize = Math.min(PARALLEL_BATCH_SIZE, variables.size());
        List<List<S7VariablesConfig>> batches = partitionList(variables, batchSize);

        List<CompletableFuture<Void>> batchTasks = new ArrayList<>();

        for (List<S7VariablesConfig> batch : batches) {
            CompletableFuture<Void> batchTask = connectionPoolManager.borrowConnection(plcIp)
                    .thenCompose(client -> {
                        // 为当前批次的变量创建并行读取任务
                        List<CompletableFuture<Void>> variableTasks = new ArrayList<>();

                        for (S7VariablesConfig variable : batch) {
                            CompletableFuture<Void> variableTask = readSingleVariable(client, variable)
                                    .thenAccept(value -> {
                                        if (value != null && variable.getVariableEnName() != null) {
                                            results.put(variable.getVariableEnName(), value);
                                            connectionPoolManager.recordReadSuccess(plcIp);
                                        }
                                    })
                                    .exceptionally(throwable -> {
                                        log.warn("读取变量 [{}] 失败: {}", variable.getVariableName(),
                                                throwable.getMessage());
                                        connectionPoolManager.recordReadFailure(plcIp);
                                        return null;
                                    });
                            variableTasks.add(variableTask);
                        }

                        // 等待当前批次的所有变量读取完成
                        return CompletableFuture.allOf(variableTasks.toArray(new CompletableFuture[0]))
                                .whenComplete((v, throwable) -> {
                                    connectionPoolManager.returnConnection(plcIp, client);
                                    if (throwable != null) {
                                        log.error("PLC [{}] 批次读取异常", plcIp, throwable);
                                    }
                                });
                    })
                    .exceptionally(throwable -> {
                        log.error("PLC [{}] 获取连接失败", plcIp, throwable);
                        return null;
                    });

            batchTasks.add(batchTask);
        }

        // 等待所有批次完成
        return CompletableFuture.allOf(batchTasks.toArray(new CompletableFuture[0]))
                .thenApply(v -> {
                    log.debug("PLC [{}] 并行读取完成，共读取{}个变量", plcIp, results.size());
                    return results;
                });
    }

    /**
     * 将列表分割成指定大小的批次
     */
    private <T> List<List<T>> partitionList(List<T> list, int batchSize) {
        List<List<T>> partitions = new ArrayList<>();
        for (int i = 0; i < list.size(); i += batchSize) {
            partitions.add(list.subList(i, Math.min(i + batchSize, list.size())));
        }
        return partitions;
    }

    /**
     * 从单个PLC读取变量 - 保留原有串行方法作为备用
     */
    private CompletableFuture<Map<String, Object>> readVariablesFromSinglePLC(String plcIp, List<S7VariablesConfig> variables) {
        Map<String, Object> results = new ConcurrentHashMap<>();

        return connectionPoolManager.borrowConnection(plcIp)
                .thenCompose(client -> {
                    CompletableFuture<Void> sequentialTask = CompletableFuture.completedFuture(null);

                    // 串行读取每个变量
                    for (S7VariablesConfig variable : variables) {
                        sequentialTask = sequentialTask.thenCompose(v ->
                            readSingleVariable(client, variable)
                                .thenApply(value -> {
                                    if (value != null && variable.getVariableEnName() != null) {
                                        results.put(variable.getVariableEnName(), value);
                                    }
                                    return (Void) null;
                                })
                                .exceptionally(throwable -> {
                                    log.warn("读取变量 [{}] 失败: {}", variable.getVariableName(),
                                            throwable.getMessage());
                                    return null;
                                })
                        );
                    }

                    return sequentialTask.thenApply(v -> {
                        connectionPoolManager.returnConnection(plcIp, client);
                        return results;
                    })
                    .exceptionally(throwable -> {
                        connectionPoolManager.returnConnection(plcIp, client);
                        log.error("PLC [{}] 读取变量异常", plcIp, throwable);
                        return results;
                    });
                });
    }

    /**
     * 读取单个变量
     */
    // 读取单个变量的主方法
    private CompletableFuture<Object> readSingleVariable(S7Client client, S7VariablesConfig variable) {
        try {
            String variableEnName = variable.getVariableEnName();
            int dbNumber = variable.getDbNumber() != null ? variable.getDbNumber().intValue() : 1;
            String startAddress = variable.getStartAddress();
            String dataType = variable.getDataType();

            if (startAddress == null || startAddress.trim().isEmpty()) {
                log.warn("变量 [{}] 没有起始地址", variableEnName);
                return CompletableFuture.completedFuture(null);
            }

            if (dataType == null || dataType.trim().isEmpty()) {
                log.warn("变量 [{}] 没有数据类型", variableEnName);
                return CompletableFuture.completedFuture(null);
            }

            String upperType = dataType.toUpperCase().trim();
            String address;

            // 针对BOOL类型特殊处理地址（保留完整格式）
            if ("BOOL".equals(upperType) || "BOOLEAN".equals(upperType)) {
                address = "DB" + dbNumber + "." + startAddress.trim().toUpperCase();
            } else {
                // 其他类型使用解析后的偏移量构建地址
                address = "DB" + dbNumber + "." + parseAddressOffset(startAddress);
            }

            log.info("读取变量 [{}]: 地址 {}, 类型 {}", variableEnName, address, upperType);

            switch (upperType) {
                case "REAL":
                case "FLOAT":
                    return client.readFloat32(address).thenApply(value -> {
                        log.info("变量 [{}] 读取成功, 值: {}", variableEnName, value);
                        return value;
                    });

                case "INT":
                case "WORD":
                    return client.readInt16(address).thenApply(value -> {
                        log.info("变量 [{}] 读取成功, 值: {}", variableEnName, value);
                        return value;
                    });

                case "LREAL":
                case "DOUBLE":
                    return client.readFloat64(address).thenApply(value -> {
                        log.info("变量 [{}] 读取成功, 值: {}", variableEnName, value);
                        return value;
                    });
                case "BOOL":
                case "BOOLEAN":
                    return client.readBool(address)
                            .thenApply(value -> {
                                log.info("变量 [{}] 读取成功, 值: {}", variableEnName, value);
                                return value;
                            });


                default:
                    log.warn("不支持的数据类型: {}", dataType);
                    return CompletableFuture.completedFuture(null);
            }
        } catch (Exception e) {
            log.error("读取变量时发生异常", e);
            return CompletableFuture.completedFuture(null);
        }
    }

    /**
     * 解析BOOL类型地址偏移
     * 格式示例: DBX10.3 → byteOffset=10, bitOffset=3
     */
    private int[] parseBoolAddress(String address) {
        try {
            String addr = address.trim().toUpperCase();
            if (addr.startsWith("DBX")) {
                String[] parts = addr.substring(3).split("\\.");
                int byteOffset = Integer.parseInt(parts[0]);
                int bitOffset = parts.length > 1 ? Integer.parseInt(parts[1]) : 0;
                return new int[]{byteOffset, bitOffset};
            }
        } catch (Exception e) {
            log.error("BOOL地址解析异常: {}", address, e);
        }
        return new int[]{0, 0};
    }


    /**
     * 解析地址偏移量
     */
    /**
     * 解析地址偏移量，支持DBX、DD、DBD等格式
     */
    // 优化后的地址偏移解析方法
    private int parseAddressOffset(String address) {
        if (address == null || address.trim().isEmpty()) {
            return 0;
        }

        String addr = address.trim().toUpperCase();

        try {
            // 处理包含分隔符的地址（如"DBX4.7"、"DBD10.2"等）
            if (addr.contains(".")) {
                String[] parts = addr.split("\\.");
                // 取第一个部分作为基础（如"DBX4.7"取"DBX4"）
                String basePart = parts[0];

                // 解析DBX格式（如"DBX4" -> 4）
                if (basePart.startsWith("DBX")) {
                    return Integer.parseInt(basePart.substring(3));
                }
                // 解析DBD格式（如"DBD10" -> 10）
                else if (basePart.startsWith("DBD")) {
                    return Integer.parseInt(basePart.substring(3));
                }
                // 解析DD格式（如"DD5" -> 5）
                else if (basePart.startsWith("DD")) {
                    return Integer.parseInt(basePart.substring(2));
                }
                // 直接解析数字部分（如"4.7"取"4"）
                else {
                    return Integer.parseInt(basePart);
                }
            }
            // 处理不包含分隔符的地址
            else {
                // 解析DBX格式（如"DBX4" -> 4）
                if (addr.startsWith("DBX")) {
                    return Integer.parseInt(addr.substring(3));
                }
                // 解析DBD格式（如"DBD10" -> 10）
                else if (addr.startsWith("DBD")) {
                    return Integer.parseInt(addr.substring(3));
                }
                // 解析DD格式（如"DD5" -> 5）
                else if (addr.startsWith("DD")) {
                    return Integer.parseInt(addr.substring(2));
                }
                // 纯数字偏移（如"4" -> 4）
                else {
                    return Integer.parseInt(addr);
                }
            }
        } catch (NumberFormatException e) {
            log.error("地址解析异常: {}", address, e);
            return 0;
        }
    }


    /**
     * 批量更新变量值
     */
    private void updateVariableValuesAsync(List<S7VariablesConfig> variables, Map<String, Object> results) {
        if (results == null || results.isEmpty()) {
            log.warn("未读取到任何变量值，无法更新数据库");
            return;
        }

        List<EquipmentVariables> updateList = new ArrayList<>();
        Date currentTime = new Date();

        // 收集需要查询的变量英文名称
        List<String> variableEnNames = new ArrayList<>();

        for (S7VariablesConfig variable : variables) {
            String variableEnName = variable.getVariableEnName();
            String variableName = variable.getVariableName();
            if (variableEnName != null && results.containsKey(variableEnName)) {
                Object value = results.get(variableEnName);
                String newValue = (value != null) ? value.toString() : "0";
                //警报
                Map<String, S7VariablesConfig> alarmS7MapCache = s7VariableManagerService.getAlarmS7MapCache();
                Map<String, Boolean> alarmS7StatusMap = s7VariableManagerService.getAlarmS7StatusMap();
                handleAlarmVariable(alarmS7MapCache, alarmS7StatusMap,variableEnName, newValue);

                // 准备更新当前变量值（保持原有逻辑）
                EquipmentVariables equipmentVariable = new EquipmentVariables();
                equipmentVariable.setVariableEnName(variableEnName);
                equipmentVariable.setVariableValue(newValue);
                equipmentVariable.setUpdateTimestamp(currentTime);
                updateList.add(equipmentVariable);

                // 收集变量英文名称，用于后续查询variable_id
                variableEnNames.add(variableEnName);

                log.debug("准备更新变量 [{}] 值: {} 并记录历史数据", variableEnName, value);

                // ==========================
                // 新增：调用能源统计
                // ==========================
                // 示例：根据PLC IP和变量英文名来判断是哪种能源
                // 这里假设每个变量都带有plcIp字段，如果没有，可以用其他方式映射
                String plcIp = variable.getPlcIp(); // 需要在S7VariablesConfig里有这个字段
                try {
                    energyDataService.processPlcData(plcIp, variableEnName, new BigDecimal(newValue));
                } catch (Exception e) {
                    log.error("处理能源数据失败: {}-{}", plcIp, variableEnName, e);
                }


            }
        }

        // 执行原有的变量值更新逻辑
        if (!updateList.isEmpty()) {
            try {
                int updatedCount = equipmentVariablesService.batchUpdateVariableValues(updateList);
                log.info("成功批量更新了 {} 个变量值", updatedCount);
            } catch (Exception e) {
                log.error("批量更新变量值失败", e);
            }
        }

        // 新增：批量保存历史数据（可配置开关）
        if (ENABLE_HISTORY_RECORDING && !variableEnNames.isEmpty()) {
            try {
                // 查询变量ID映射
                List<EquipmentVariables> existingVariables = equipmentVariablesService.selectEquipmentVariablesByEnNames(variableEnNames);
                Map<String, Long> variableIdMap = new HashMap<>();
                for (EquipmentVariables var : existingVariables) {
                    variableIdMap.put(var.getVariableEnName(), var.getVariableId());
                }

                // 准备历史数据记录
                List<EquipmentVariablesHistory> historyList = new ArrayList<>();
                for (S7VariablesConfig variable : variables) {
                    String variableEnName = variable.getVariableEnName();
                    if (variableEnName != null && results.containsKey(variableEnName)) {
                        Object value = results.get(variableEnName);
                        String newValue = (value != null) ? value.toString() : "0";
                        Long variableId = variableIdMap.get(variableEnName);

                        if (variableId != null) {
                            EquipmentVariablesHistory historyRecord = new EquipmentVariablesHistory();
                            historyRecord.setVariableId(variableId); // 设置变量ID
                            historyRecord.setVariableName(variable.getVariableName());
                            historyRecord.setVariableEnName(variableEnName);
                            historyRecord.setVariableValue(newValue);
                            historyRecord.setRecordTimestamp(currentTime);
                            historyRecord.setOperationType("S7_READ"); // 标识为S7读取操作
                            historyRecord.setNewValue(newValue);
                            historyRecord.setOldValue(null); // 读取操作无旧值
                            historyList.add(historyRecord);
                        } else {
                            log.warn("未找到变量 [{}] 的ID，跳过历史数据记录", variableEnName);
                        }
                    }
                }

                if (!historyList.isEmpty()) {
                    int historyCount = equipmentVariablesHistoryService.batchInsertEquipmentVariablesHistory(historyList);
                    log.info("成功批量保存了 {} 条变量历史数据", historyCount);
                } else {
                    log.warn("没有有效的历史数据需要保存");
                }
            } catch (Exception e) {
                log.error("批量保存变量历史数据失败", e);
            }
        }
    }

    /**
     * 报警PLC
     * @param alarmS7MapCache
     * @param alarmS7StatusMap
     * @param variableEnName
     * @param value
     */
    private void handleAlarmVariable(Map<String, S7VariablesConfig> alarmS7MapCache,
                                     Map<String, Boolean> alarmS7StatusMap,
                                     String variableEnName,
                                     Object value) {
        //是否报警plc
        if(alarmS7MapCache.containsKey(variableEnName)) {
            S7VariablesConfig alarmS7VariablesConfig = alarmS7MapCache.get(variableEnName);

            boolean currentValue = parseBoolean(value);
            Boolean lastValue = alarmS7StatusMap.get(variableEnName);
            //更新状态缓存
            alarmS7StatusMap.put(variableEnName, currentValue);

            if ((lastValue == null || !lastValue) && currentValue) {
                // false -> true 触发报警
                AlarmInfo alarm = new AlarmInfo();
                alarm.setId(IdUtil.getSnowflakeNextId());
                alarm.setAlarmLevel(1);
                alarm.setAlarmContent(alarmS7VariablesConfig.getVariableName());
                alarm.setAlarmTime(new Date());
                alarmService.save(alarm);
                log.info("触发新报警: {}", alarm);
            }
        }
    }

    /**
     * object转bool
     * @param value
     * @return
     */
    private boolean parseBoolean(Object value) {
        if (value == null) {
            return false;
        }
        if (value instanceof Boolean) {
            return (Boolean) value;
        }
        if (value instanceof Number) {
            return ((Number) value).intValue() != 0;
        }
        String str = String.valueOf(value).trim();
        return "true".equalsIgnoreCase(str) || "1".equals(str);
    }


    /**
     * 检查PLC连接状态
     */
    public boolean isConnected(String plcIp) {
        return connectionPoolManager.isConnected(plcIp);
    }

    /**
     * 获取读取性能统计信息
     */
    public Map<String, Object> getReadingPerformanceStats() {
        Map<String, Object> stats = new HashMap<>();
        List<String> plcIps = s7VariableManagerService.getAllPlcIps();

        for (String plcIp : plcIps) {
            Map<String, Object> plcStats = connectionPoolManager.getPlcMonitoringInfo(plcIp);
            stats.put(plcIp, plcStats);
        }

        stats.put("parallelReadingEnabled", ENABLE_PARALLEL_READING);
        stats.put("batchSize", PARALLEL_BATCH_SIZE);
        stats.put("maxRetryCount", MAX_RETRY_COUNT);
        stats.put("historyRecordingEnabled", ENABLE_HISTORY_RECORDING);

        return stats;
    }

    /**
     * 手动触发一次变量读取（用于测试）
     */
    public CompletableFuture<Map<String, Object>> triggerManualRead() {
        log.info("手动触发变量读取...");
        long startTime = System.currentTimeMillis();

        List<String> plcIps = s7VariableManagerService.getAllPlcIps();
        List<CompletableFuture<Map<String, Object>>> plcReadTasks = new ArrayList<>();
        List<S7VariablesConfig> allVariables = new ArrayList<>();

        for (String plcIp : plcIps) {
            List<S7VariablesConfig> variables = s7VariableManagerService.getVariablesByPlcIp(plcIp);

            if (!variables.isEmpty() && connectionPoolManager.isConnected(plcIp)) {
                allVariables.addAll(variables);
                CompletableFuture<Map<String, Object>> plcTask = ENABLE_PARALLEL_READING
                    ? readVariablesFromSinglePLCParallel(plcIp, variables)
                    : readVariablesFromSinglePLC(plcIp, variables);
                plcReadTasks.add(plcTask);
            }
        }

        if (plcReadTasks.isEmpty()) {
            return CompletableFuture.completedFuture(new HashMap<>());
        }

        return CompletableFuture.allOf(plcReadTasks.toArray(new CompletableFuture[0]))
                .thenApply(v -> {
                    Map<String, Object> allResults = new ConcurrentHashMap<>();
                    for (CompletableFuture<Map<String, Object>> task : plcReadTasks) {
                        try {
                            Map<String, Object> plcResults = task.get();
                            allResults.putAll(plcResults);
                        } catch (Exception e) {
                            log.error("获取手动读取结果时发生异常", e);
                        }
                    }

                    long duration = System.currentTimeMillis() - startTime;
                    log.info("手动读取完成，读取{}个变量，用时{}ms", allResults.size(), duration);

                    // 添加性能信息到结果中
                    Map<String, Object> performanceInfo = new HashMap<>();
                    performanceInfo.put("duration", duration);
                    performanceInfo.put("variableCount", allResults.size() - 1); // 减去性能信息本身
                    performanceInfo.put("plcCount", plcReadTasks.size());
                    performanceInfo.put("parallelEnabled", ENABLE_PARALLEL_READING);
                    allResults.put("_performance", performanceInfo);

                    return allResults;
                });
    }

    /**
     * 销毁资源
     */
    @PreDestroy
    public void destroy() {
        log.info("正在关闭S7连接管理服务...");

        // 关闭定时任务
        scheduler.shutdown();

        // 关闭连接池
        connectionPoolManager.destroy();

        log.info("S7连接管理服务已关闭");
    }
}
